﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using NLog;

namespace LogToDB
{
    class NLogToDB
    {
        /*单实例 第一次初始化 检测表结构
         * 检查表名 是否存在
         每次插入检查 表是否存在，不存在新建表 
         //写不进数据库时 写入日志文件，
             */

        private static int m_server_id = 0;
        private NLogToDB(int server_id)
        {
            //初始化时 检查所有 存在的表 中的字字段 正确 
            m_server_id = server_id;
            CheckTableStructure(m_server_id);


        }
        private Dictionary<string, string> tableNameDic = new Dictionary<string, string>();
        public static NLogToDB Instance(int server_id)
        {
            if (instance == null)
            {
                instance = new NLogToDB(server_id);
            }
            return instance;
        }
        public static NLogToDB instance = null;
        //检查所有已存在的表的结构 是否正确
        public void CheckTableStructure(int server_id) {
            foreach (int myCode in Enum.GetValues(typeof(LogType))) {
                string strName = Enum.GetName(typeof(LogType), myCode);//获取名称
                string tableName = GetTabelName(server_id, strName);
                MysqlDB.CheckTableStructure<LogInst>(tableName);                
            }

        }
        // 检查表是否存在 表结构是否正确。
        private bool CheckTable(string tableName) {
            bool res = false;
            lock (tableNameDic) {
                if (!tableNameDic.ContainsKey(tableName))
                {
                    if (MysqlDB.IsTableExists(tableName))
                    {
                        res = true;
                    }
                    else
                    {
                        int i = 0;
                        while (i<3) {
                            //不存在创建新,尝试3次
                            MysqlDB.ReflectionCreateTable<LogInst>(tableName);
                            if (MysqlDB.IsTableExists(tableName)) {
                                res = true;
                                break;
                                //直接跳出循环
                            }
                            i += 1;
                        }
                    }
                    if(res)
                    {
                        tableNameDic.Add(tableName, tableName);
                    }                  
                }
                else
                {
                    res = true;
                } 
            }
            //测试只写数据库 用
           // res = false;
            return res;
        }

        public void AddLog( int accountid, int roleid, LogType ltype, EventType etype, int event_id, int event_value, int target_id, int target_value, string info)
        {           
          
            LogInst inst = new LogInst();
            inst.ServerID = m_server_id;
            inst.AccountID = accountid;
            inst.RoleID = roleid;
            inst.LType = ltype;
            inst.EType = etype;
            inst.EventID = event_id;
            inst.EventValue = event_value;
            inst.TargetID = target_id;
            inst.TargetValue = target_value;
            inst.Info = info;
            inst.LogTime = DateTime.Now;
            AddLog(inst);

        }

        public void AddLog(LogInst inst)
        {
            try
            {
                var tableName = GetTabelName(inst.ServerID, inst.LType.ToString());
                Logger logger = LogManager.GetCurrentClassLogger();

                LogEventInfo log = new LogEventInfo();
                if (CheckTable(tableName))
                {
                    //表存在  写入数据库 日志文件
                    // WriteLogToDB(inst, tableName); 
                    log.Level = LogLevel.Fatal;
                }
                else
                {
                    //表不存在  直接写日志文件
                    log.Level = LogLevel.Debug;
                    // WriteLogToFile(inst);
                }
                log.Message = MysqlDB.GetDBMessage(inst, tableName);
                
                logger.Log(log);
            }
            catch (Exception e) {             
                Util.WriteLog(e.ToString());
            }
        }

        private void WriteLogToDB(LogInst inst,string tableName) {
            Logger logger = LogManager.GetCurrentClassLogger();
            LogEventInfo log = new LogEventInfo();
            log.Level = LogLevel.Fatal; ;
            log.Message = MysqlDB.GetDBMessage(inst,tableName);
            logger.Log(log);
        }
        private void WriteLogToFile(LogInst inst)
        {
            Logger logger = LogManager.GetCurrentClassLogger();
            LogEventInfo log = new LogEventInfo();
            log.Level = LogLevel.Debug;
            log.Message = CommonFuction.GetFileMessage<LogInst>(inst);
            logger.Log(log);
        }
       

        //获取表名 日志类型 + 日期 + serverid
        private string GetTabelName(int serverid,string ltype) {          
            DateTime dt = DateTime.Now;
            string tableName =  serverid.ToString() + "_" + ltype + "_" + string.Format("{0:yyyyMM}", dt);
            return tableName;
        }
        
    }
}
